package com.chengh.nami.system.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.chengh.nami.common.domain.pojo.SysDictData;
import com.chengh.nami.common.exception.BizException;
import com.chengh.nami.common.request.PageQuery;
import com.chengh.nami.common.response.PageData;
import com.chengh.nami.common.utils.DictUtils;
import com.chengh.nami.common.utils.StringUtils;
import com.chengh.nami.system.domain.dto.DictTypeDto;
import com.chengh.nami.system.mapper.SysDictTypeMapper;
import com.chengh.nami.system.pojo.SysDictType;
import com.chengh.nami.system.service.ISysDictDataService;
import com.chengh.nami.system.service.ISysDictTypeService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.PostConstruct;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Slf4j
@Service
@RequiredArgsConstructor
public class SysDictTypeServiceImpl extends ServiceImpl<SysDictTypeMapper, SysDictType> implements ISysDictTypeService {

    private final ISysDictDataService sysDictDataService;

    /**
     * 项目启动时，初始化字典到缓存
     */
    @PostConstruct
    public void init() {
        loadingDictCache();
    }

    /**
     * 加载字典缓存数据
     */
    @Override
    public void loadingDictCache() {
        List<SysDictData> dictDataByTypes = sysDictDataService.getDictDataList();
        Map<String, List<SysDictData>> dictDataMap = dictDataByTypes.stream().collect(Collectors.groupingBy(SysDictData::getDictType));
        for (Map.Entry<String, List<SysDictData>> entry : dictDataMap.entrySet()) {
            List<SysDictData> collect = entry.getValue().stream().sorted(Comparator.comparing(SysDictData::getDictSort)).collect(Collectors.toList());
            log.info("开始写入缓存: {}, {}", entry.getKey(), collect);
            DictUtils.setDictCache(entry.getKey(), collect);
        }
        log.info("缓存写入成功");
    }

    /**
     * 清除缓存
     */
    private void clearDictCache() {
        DictUtils.clearDictCache();
    }


    @Override
    public List<SysDictType> getList(DictTypeDto dictTypeDto) {
        LambdaQueryWrapper<SysDictType> wrapper = new LambdaQueryWrapper<SysDictType>().eq(StringUtils.isNotEmpty(dictTypeDto.getDictType()), SysDictType::getDictType, dictTypeDto.getDictType())
                .like(StringUtils.isNotEmpty(dictTypeDto.getDictName()), SysDictType::getDictName, dictTypeDto.getDictName());
        return baseMapper.selectList(wrapper);
    }

    @Override
    public PageData<SysDictType> getListType(DictTypeDto dictTypeDto, PageQuery pageQuery) {
        Page<SysDictType> build = pageQuery.build();
        LambdaQueryWrapper<SysDictType> wrapper = new LambdaQueryWrapper<SysDictType>().eq(StringUtils.isNotEmpty(dictTypeDto.getDictType()), SysDictType::getDictType, dictTypeDto.getDictType())
                .like(StringUtils.isNotEmpty(dictTypeDto.getDictName()), SysDictType::getDictName, dictTypeDto.getDictName());
        Page<SysDictType> sysDictTypePage = baseMapper.selectPage(build, wrapper);
        return PageData.build(sysDictTypePage);
    }

    @Override
    public Boolean edit(SysDictType dictType) {
        verifyRepeat(dictType);
        int i = this.baseMapper.updateById(dictType);
        if (i > 0) {
            List<SysDictData> dictDataByType = sysDictDataService.getDictDataByTypeNoCache(dictType.getDictType());
            DictUtils.setDictCache(dictType.getDictType(), dictDataByType);
            log.info("修改字典类型后, 存入redis成功");
        }
        return i > 0;
    }

    @Override
    public Boolean addDict(SysDictType sysDictType) {
        verifyRepeat(sysDictType);
        return baseMapper.insert(sysDictType) > 0;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void delDict(Long[] ids) {
        for (Long id : ids) {
            // 根据ID获取字典类型信息
            Integer countData = baseMapper.countData(id);
            if (countData > 0) {
                throw new BizException("编号为[" + id + "]不能删除, 需要删除子数据项");
            }
            baseMapper.deleteById(id);
        }
    }

    @Override
    public void refreshCache() {
        clearDictCache();
        loadingDictCache();
    }

    /**
     * 校验字典类型是否重复
     *
     * @param dictType 字典类型i西南西
     */
    public void verifyRepeat(SysDictType dictType) {
        LambdaQueryWrapper<SysDictType> wrapper = new LambdaQueryWrapper<SysDictType>().eq(SysDictType::getDictType, dictType.getDictType())
                .ne(dictType.getId() != null, SysDictType::getId, dictType.getId());
        Long aLong = this.baseMapper.selectCount(wrapper);
        if (aLong > 0) {
            throw new BizException("字典类型重复");
        }
    }
}
